﻿using Account.Api.Client;
using Account.Api.Dtos;
using Blazored.LocalStorage;
using Cyss.Core;
using Cyss.Core.Models;
using CyssBlazor.Shared.Infrastructure;
using CyssBlazor.Shared.Models;
using System.Linq;
using System.Threading.Tasks;

namespace CyssBlazor.WebAssembly.Infrastructure
{
    public class UserAuthenService : IUserAuthenService
    {
        private IUserAuthStateProvider _authenticationStateProvider;
        private ILocalStorageService _localStorage;
        private IBlazorWorkContext _workContext;
        public UserAuthenService(
            IUserAuthStateProvider authenticationStateProvider,
             IBlazorWorkContext workContext,
            ILocalStorageService localStorage
            )
        {
            _workContext=workContext;
            _localStorage =localStorage;
            _authenticationStateProvider = authenticationStateProvider;
        }

        public async Task<string> GetLoginUserName()
        {
            var userName = await _localStorage.GetItemAsStringAsync("authUser");
            if (string.IsNullOrWhiteSpace(userName))
            {
                userName = string.Empty;
            }
            return userName;
        }

        public async Task<AuthenticationUser> GetCurrentUserAsync()
        {
            if (_workContext.User != null)
            {
                return _workContext.User;
            }
            var savedToken = await _localStorage.GetItemAsync<string>("authToken");
            if (string.IsNullOrWhiteSpace(savedToken))
            {
                return null;
            }

            var apiResponse = await AccountClientFactory.User.TokenLogin(savedToken);
            if (apiResponse.IsSuccess && apiResponse.Data != null)
            {
                _workContext.User = new AuthenticationUser();
                _workContext.User.Id = apiResponse.Data.Id;
                _workContext.User.Name = apiResponse.Data.Name;
                _workContext.User.UserNo = apiResponse.Data.No;
                _workContext.UserRoles = apiResponse.Data.UserRoles.ToList();
                _workContext.Menus=apiResponse.Data.Menus.ToList();
                _workContext.Token = savedToken;
                _workContext.IsLogin = true;
                return _workContext.User;
            }

            return null;

        }

        public async Task<bool> LoginAsync(LoginViewModel loginModel)
        {

            var apiResponse = await AccountClientFactory.User.Login(loginModel.ToObject<LoginModel>());

            if (apiResponse.IsSuccess && apiResponse.Data != null)
            {
                await _localStorage.SetItemAsync<string>("authUser", apiResponse.Data.Name);
                await _localStorage.SetItemAsync<string>("authToken", apiResponse.Data.Token.TokenStr);

                _workContext.Token = apiResponse.Data.Token.TokenStr;
                _workContext.User = new AuthenticationUser();
                _workContext.User.Id = apiResponse.Data.Id;
                _workContext.User.Name = apiResponse.Data.Name;
                _workContext.User.UserNo = apiResponse.Data.No;
                _workContext.UserRoles = apiResponse.Data.UserRoles.ToList();
                _workContext.Menus=apiResponse.Data.Menus.ToList();
                _workContext.Permissions = apiResponse.Data.Permissions.ToList();
                _workContext.IsLogin = true;
                return true;
            }
            _workContext.IsLogin = false;
            return false;
        }

        public async Task LogoutAsync()
        {
            _workContext.IsLogin = false;
            _workContext.Token = string.Empty;
            _workContext.User = null;
            await _localStorage.RemoveItemAsync("authToken");
            _authenticationStateProvider.LogUserOut();
        }

        public async Task<OperateResult<bool>> ValiToken()
        {
            OperateResult<bool> apiResponse = new OperateResult<bool>();
            var savedToken = await _localStorage.GetItemAsync<string>("authToken");
            if (string.IsNullOrWhiteSpace(savedToken))
            {
                apiResponse.IsSuccess = true;
                apiResponse.Data = false;
                return apiResponse;
            }
            var responseToken = await AccountClientFactory.User.ValiToken(savedToken);
            return responseToken;
        }


    }
}
